<?php
namespace Lib;

defined('THINK_PATH') or exit();

class JsonRPC
{
    private $_conn;
    private $_error;
    private $_host;
    private $_port;
    private static $_class;
    public function __construct($host = '', $port = '')
    {
        !$host and $host = $_SERVER['SRV_GORPC_HOST'];
        !$port and $port = $_SERVER['SRV_GORPC_PORT'];
        $this->_host     = $host;
        $this->_port     = $port;
        $this->_conn     = fsockopen($host, $port, $errno, $errstr, 3);
        if (!$this->_conn) {
            $this->_error = $errstr;
        }
    }

    /* =================== 单例方法 =================== */
    public static function getInstance()
    {
        if (self::$_class == null) {
            self::$_class = new self();
        }
        return self::$_class;
    }

    public function callMethod($method, $params = '')
    {
        if (!$this->_conn) {
            return false;
        }
        $json           = array('id' => 0, 'method' => $method);
        $json['params'] = !$params ? array() : array($params);
        $err            = fwrite($this->_conn, json_encode($json) . "\n");
        if ($err === false) {
            $this->_error = "cannot write to {$this->_host}:{$this->_port}";
            return false;
        }
        $line = fgets($this->_conn);
        if ($line === false) {
            $this->_error = "cannot read from {$this->_host}:{$this->_port}";
            return false;
        }
        $ret = json_decode($line, 1);
        if (!$ret) {
            $this->_error = "wrong json format:$line";
            return false;
        }
        if($ret['error']){
            $this->_error = $ret['error'];
            return false;
        }
        return $ret['result'];
    }

    public function getError()
    {
        return $this->_error;
    }

    public function close()
    {
        self::$_class = null;
        fclose($this->_conn);
    }
}
